import {login, logout, getInfo} from "../../api/user";
import {qrcodeWxLogin} from "../../api/wx";
import {
    getToken,
    setToken,
    removeToken,
    getLocalEmail,
    setLocalEmail,
    removeLocalEmail,
    getApp,
    setApp,
    removeApp,
    setWechatAccount,
    getWechatAccount,
    removeWechatAccount,
    getAppId,
    setAppId,
    removeAppId,
    getStoreInfo,
    setStoreInfo,
    removeStoreInfo
} from "../../utils/auth";
import router from "../../router";

const state = {
    token: getToken(),
    name: "",
    avatar: "",
    introduction: "",
    roles: [],
    permissions: [],
    email: getLocalEmail(),
    id: "",
    app: getApp(),
    wechatAccount: getWechatAccount(),
    appid: getAppId(),
    storeinfo: getStoreInfo() === undefined ? {} : JSON.parse(getStoreInfo())
};

const mutations = {
    SET_TOKEN: (state, token) => {
        state.token = token;
    },
    SET_INTRODUCTION: (state, introduction) => {
        state.introduction = introduction;
    },
    SET_NAME: (state, name) => {
        state.name = name;
    },
    SET_AVATAR: (state, avatar) => {
        state.avatar = avatar;
    },
    SET_ROLES: (state, roles) => {
        state.roles = roles;
    },
    SET_PERMISSIONS: (state, permissions) => {
        state.permissions = permissions;
    },
    SET_EMAIL: (state, email) => {
        state.email = email;
    },
    SET_USER_ID: (state, id) => {
        state.id = id;
    },
    SET_APP: (state, app) => {
        state.app = app;
    },
    SET_WECHATACCOUNT: (state, account) => {
        state.wechatAccount = account;
    },
    SET_APPID: (state, appid) => {
        state.appid = appid;
    },
    SET_STORE_INFO: (state, info) => {
        state.storeinfo = info;
    }
};

const actions = {
    // user login
    login({commit}, userInfo) {
        const {email, password} = userInfo;
        return new Promise((resolve, reject) => {
            login({email: email.trim(), password: password})
                .then(response => {
                    const data = response.data;
                    commit("SET_TOKEN", data.token);
                    setToken(data.token);
                    resolve();
                })
                .catch(error => {
                    reject(error);
                });
        });
    },
    // wechat login
    wechatLogin({commit}, userInfo) {
        return new Promise((resolve, reject) => {
            qrcodeWxLogin(userInfo)
                .then(response => {
                    const data = response.data;
                    commit("SET_TOKEN", data.token);
                    removeToken();
                    setToken(data.token);
                    resolve();
                })
                .catch(error => {
                    reject(error);
                });
        });
    },
    // get user info
    getInfo({commit, state}) {
        return new Promise((resolve, reject) => {
            getInfo(state.token)
                .then(response => {
                    const {data} = response;

                    if (!data) {
                        reject("Verification failed, please Login again.");
                    }

                    const {
                        id,
                        roles,
                        username,
                        avatar,
                        introduction,
                        permissions,
                        email
                    } = data;

                    // roles must be a non-empty array
                    if (!roles || roles.length <= 0) {
                        reject("getInfo: roles must be a non-null array!");
                    }
                    commit("SET_ROLES", roles);
                    commit("SET_NAME", username);
                    commit("SET_AVATAR", avatar);
                    commit("SET_INTRODUCTION", introduction);
                    commit("SET_PERMISSIONS", permissions);
                    commit("SET_EMAIL", email);
                    setLocalEmail(email);
                    commit("SET_USER_ID", id);
                    resolve(data);
                })
                .catch(error => {
                    reject(error);
                });
        });
    },

    // user logout
    logout({commit, state, dispatch}) {
        return new Promise((resolve, reject) => {
            logout(state.token)
                .then(() => {
                    commit("SET_TOKEN", "");
                    commit("SET_EMAIL", "");
                    commit("SET_ROLES", []);
                    commit("SET_WECHATACCOUNT", "");
                    commit("SET_APPID", "");
                    commit("SET_STORE_INFO", "");
                    removeToken();
                    removeLocalEmail();
                    removeApp();
                    removeWechatAccount();
                    removeAppId();
                    removeStoreInfo();

                    // reset visited views and cached views
                    // to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2485
                    dispatch("tagsView/delAllViews", null, {root: true});

                    resolve();
                })
                .catch(error => {
                    reject(error);
                });
        });
    },

    // remove token
    resetToken({commit}) {
        return new Promise(resolve => {
            commit("SET_TOKEN", "");
            commit("SET_ROLES", []);
            removeToken();
            resolve();
        });
    },

    // dynamically modify permissions
    async changeRoles({commit, dispatch}, role) {
        const token = role + "-token";

        commit("SET_TOKEN", token);
        setToken(token);

        const {roles} = await dispatch("getInfo");

        // generate accessible routes map based on roles
        const accessRoutes = await dispatch("permission/generateRoutes", roles, {
            root: true
        });
        // dynamically add accessible routes
        router.addRoutes(accessRoutes);

        // reset visited views and cached views
        dispatch("tagsView/delAllViews", null, {root: true});
    },
    setUserApp({commit}, app) {
        commit("SET_APP", app.name);
        setApp(app.name);
        commit("SET_APPID", app.appid);
        setAppId(app.appid);
    },
    setWechatAccount({commit}, account) {
        commit("SET_WECHATACCOUNT", account);
        removeWechatAccount();
        setWechatAccount(account);
    },
    // 应用市场登入
    loginStore({commit}, info) {
        commit("SET_STORE_INFO", info);
        setStoreInfo(info);
    },
    // 应用市场登出
    logoutStore({commit}) {
        commit("SET_STORE_INFO", {});
        removeStoreInfo();
    }
};

export default {
    namespaced: true,
    state,
    mutations,
    actions
};
